package com.fand.platform.userCenter.service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.fand.dto.PaginationDto;
import com.fand.platform.userCenter.dao.UserDao;
import com.fand.platform.userCenter.dto.UserDto;
import com.fand.platform.userCenter.dto.UserLoInDto;
import com.fand.platform.userCenter.dto.UserReDto;

/**
 * 用户服务
 *
 * @author yaoHT
 * 
 */
@Getter 
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class UserDefaultService implements UserService {
	private UserDao userDao;
	
	@Override
	@CacheEvict(value = UserService.CACHE_NAME, allEntries = true)
	public void reload() {
	}

	@Override
	@Transactional
	public UserDto saveUserByIdOrCodeForUser(UserDto saveUser) {
		String[] whereEqProperties = null;

//		if (StringUtils.isNotBlank(saveUser.getId())) {
//			whereEqProperties = new String[] { "id" };
//		} else {
//			whereEqProperties = new String[] { "code" };
//		}
	
		UserDto oldUser = this.userDao.selectUserBy1ForMappedObject(UserDto.class,
				saveUser, null, whereEqProperties);

		if (oldUser == null) {
			this.userDao.insertUserBy1(saveUser);

			return saveUser;
		}
		
		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveUser, oldUser, "code", "name");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.userDao.updateUserBy1(saveUser, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveUser, oldUser, updateProperties);
		}

		return oldUser;
	}

	@Override
	@Transactional
	public UserDto saveUserBy2ForUser(UserDto saveUser) {
		String[] whereEqProperties = null;

//		if (StringUtils.isNotBlank(saveUser.getId())) {
//			whereEqProperties = new String[] { "id" };
//		} else {
//			whereEqProperties = new String[] { "code" };
//		}
	
		UserDto oldUser = this.userDao.selectUserBy1ForMappedObject(UserDto.class,
				saveUser, null, whereEqProperties);

		if (oldUser == null) {
			this.userDao.insertUserBy1(saveUser, new String[] {});

			return saveUser;
		}
		
		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveUser, oldUser, "code", "name");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.userDao.updateUserBy1(saveUser, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveUser, oldUser, updateProperties);
		}

		return oldUser;
	}

	@Override
	@Transactional
	public int deleteUserBy1(UserDto deleteUser) {
		return this.userDao.deleteUserBy1(deleteUser, new String[] {});
	}

	@Override
	@Transactional
	public int deleteUserByIds(UserDto deleteUser) {
		return this.userDao.deleteUserByIds(deleteUser);
	}

	@Override
	@Transactional
	public int setUserBy1(UserDto setUser) {
		return this.userDao.updateUserBy1(setUser, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setUserBy2(UserDto setUser) {
		return this.userDao.updateUserBy2(setUser);
	}

	@Override
	public Integer readUserByCodeNqIdForInteger(UserDto readUser) {
		return this.userDao.selectUserByCodeNqIdForInteger(readUser);
	}

	@Override
	public Integer readUserBy2ForInteger(UserDto readUser) {
		return this.userDao.selectUserBy2ForObject(Integer.class, readUser, null);
	}

	@Override
	public List<Integer> readListUserBy1(UserDto readUser) {
		return this.userDao.selectUserBy1ForObjectList(Integer.class, readUser, null,
				new String[] {});
	}

	@Override
	public List<Integer> readListUserBy2(UserDto readUser) {
		return this.userDao.selectUserBy2ForObjectList(Integer.class, readUser, null);
	}

	@Override
	public UserDto getUserBy1(UserDto getUser) {
		return this.userDao.selectUserBy1ForMappedObject(UserDto.class, getUser, null, "id");
	}

	@Override
	public UserDto getUserById(UserDto getUser) {
		return this.userDao.selectUserBy1ForMappedObject(UserDto.class, getUser, null, "id");
	}

	@Override
	public List<UserDto> findUserBy1(UserDto findUser) {
		return this.userDao.selectUserBy1ForMappedObjectList(UserDto.class, findUser,
				new String[] {}, new String[] {});
	}

	@Override
	public List<UserDto> findUserBy2(UserDto findUser) {
		return this.userDao.selectUserBy2ForMappedObjectList(UserDto.class, findUser);
	}

	@Override
	public PaginationDto<UserDto> paginationUserBy1ForUserList(UserDto paginationUser) {
		return this.userDao.paginationUserBy1ForMappedObjectList(UserDto.class,
				paginationUser);
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationUserBy1ForMapList(UserDto paginationUser) {
		return this.userDao.paginationUserBy1ForMapList(paginationUser);
	}

	@Override
	@Transactional
	public UserLoInDto saveUserLoInByIdOrCodeForUserLoIn(UserLoInDto saveUserLoIn) {
		String[] whereEqProperties = null;

//		if (StringUtils.isNotBlank(saveUserLoIn.getId())) {
//			whereEqProperties = new String[] { "id" };
//		} else {
//			whereEqProperties = new String[] { "code" };
//		}
	
		UserLoInDto oldUserLoIn = this.userDao.selectUserLoInBy1ForMappedObject(UserLoInDto.class,
				saveUserLoIn, null, whereEqProperties);

		if (oldUserLoIn == null) {
			this.userDao.insertUserLoInBy1(saveUserLoIn);

			return saveUserLoIn;
		}
		
		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveUserLoIn, oldUserLoIn, "code", "name");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.userDao.updateUserLoInBy1(saveUserLoIn, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveUserLoIn, oldUserLoIn, updateProperties);
		}

		return oldUserLoIn;
	}

	@Override
	@Transactional
	public UserLoInDto saveUserLoInBy2ForUserLoIn(UserLoInDto saveUserLoIn) {
		String[] whereEqProperties = null;

//		if (StringUtils.isNotBlank(saveUserLoIn.getId())) {
//			whereEqProperties = new String[] { "id" };
//		} else {
//			whereEqProperties = new String[] { "code" };
//		}
	
		UserLoInDto oldUserLoIn = this.userDao.selectUserLoInBy1ForMappedObject(UserLoInDto.class,
				saveUserLoIn, null, whereEqProperties);

		if (oldUserLoIn == null) {
			this.userDao.insertUserLoInBy1(saveUserLoIn, new String[] {});

			return saveUserLoIn;
		}
		
		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveUserLoIn, oldUserLoIn, "code", "name");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.userDao.updateUserLoInBy1(saveUserLoIn, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveUserLoIn, oldUserLoIn, updateProperties);
		}

		return oldUserLoIn;
	}

	@Override
	@Transactional
	public int deleteUserLoInBy1(UserLoInDto deleteUserLoIn) {
		return this.userDao.deleteUserLoInBy1(deleteUserLoIn, new String[] {});
	}

	@Override
	@Transactional
	public int deleteUserLoInByIds(UserLoInDto deleteUserLoIn) {
		return this.userDao.deleteUserLoInByIds(deleteUserLoIn);
	}

	@Override
	@Transactional
	public int setUserLoInBy1(UserLoInDto setUserLoIn) {
		return this.userDao.updateUserLoInBy1(setUserLoIn, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setUserLoInBy2(UserLoInDto setUserLoIn) {
		return this.userDao.updateUserLoInBy2(setUserLoIn);
	}

	@Override
	public Integer readUserLoInByCodeNqIdForInteger(UserLoInDto readUserLoIn) {
		return this.userDao.selectUserLoInByCodeNqIdForInteger(readUserLoIn);
	}

	@Override
	public Integer readUserLoInBy2ForInteger(UserLoInDto readUserLoIn) {
		return this.userDao.selectUserLoInBy2ForObject(Integer.class, readUserLoIn, null);
	}

	@Override
	public List<Integer> readListUserLoInBy1(UserLoInDto readUserLoIn) {
		return this.userDao.selectUserLoInBy1ForObjectList(Integer.class, readUserLoIn, null,
				new String[] {});
	}

	@Override
	public List<Integer> readListUserLoInBy2(UserLoInDto readUserLoIn) {
		return this.userDao.selectUserLoInBy2ForObjectList(Integer.class, readUserLoIn, null);
	}

	@Override
	public UserLoInDto getUserLoInBy1(UserLoInDto getUserLoIn) {
		return this.userDao.selectUserLoInBy1ForMappedObject(UserLoInDto.class, getUserLoIn, null, "id");
	}

	@Override
	public UserLoInDto getUserLoInById(UserLoInDto getUserLoIn) {
		return this.userDao.selectUserLoInBy1ForMappedObject(UserLoInDto.class, getUserLoIn, null, "id");
	}

	@Override
	public List<UserLoInDto> findUserLoInBy1(UserLoInDto findUserLoIn) {
		return this.userDao.selectUserLoInBy1ForMappedObjectList(UserLoInDto.class, findUserLoIn,
				new String[] {}, new String[] {});
	}

	@Override
	public List<UserLoInDto> findUserLoInBy2(UserLoInDto findUserLoIn) {
		return this.userDao.selectUserLoInBy2ForMappedObjectList(UserLoInDto.class, findUserLoIn);
	}

	@Override
	public PaginationDto<UserLoInDto> paginationUserLoInBy1ForUserLoInList(UserLoInDto paginationUserLoIn) {
		return this.userDao.paginationUserLoInBy1ForMappedObjectList(UserLoInDto.class,
				paginationUserLoIn);
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationUserLoInBy1ForMapList(UserLoInDto paginationUserLoIn) {
		return this.userDao.paginationUserLoInBy1ForMapList(paginationUserLoIn);
	}

	@Override
	@Transactional
	public UserReDto saveUserReByIdOrCodeForUserRe(UserReDto saveUserRe) {
		String[] whereEqProperties = null;

//		if (StringUtils.isNotBlank(saveUserRe.getId())) {
//			whereEqProperties = new String[] { "id" };
//		} else {
//			whereEqProperties = new String[] { "code" };
//		}
	
		UserReDto oldUserRe = this.userDao.selectUserReBy1ForMappedObject(UserReDto.class,
				saveUserRe, null, whereEqProperties);

		if (oldUserRe == null) {
			this.userDao.insertUserReBy1(saveUserRe);

			return saveUserRe;
		}
		
		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveUserRe, oldUserRe, "code", "name");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.userDao.updateUserReBy1(saveUserRe, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveUserRe, oldUserRe, updateProperties);
		}

		return oldUserRe;
	}

	@Override
	@Transactional
	public UserReDto saveUserReBy2ForUserRe(UserReDto saveUserRe) {
		String[] whereEqProperties = null;

//		if (StringUtils.isNotBlank(saveUserRe.getId())) {
//			whereEqProperties = new String[] { "id" };
//		} else {
//			whereEqProperties = new String[] { "code" };
//		}
	
		UserReDto oldUserRe = this.userDao.selectUserReBy1ForMappedObject(UserReDto.class,
				saveUserRe, null, whereEqProperties);

		if (oldUserRe == null) {
			this.userDao.insertUserReBy1(saveUserRe, new String[] {});

			return saveUserRe;
		}
		
		String[] updateProperties = com.fand.utils.BeanUtils.differProperties(saveUserRe, oldUserRe, "code", "name");

		if (ArrayUtils.isNotEmpty(updateProperties)) {
			this.userDao.updateUserReBy1(saveUserRe, updateProperties, whereEqProperties);

			com.fand.utils.BeanUtils.copyProperties(saveUserRe, oldUserRe, updateProperties);
		}

		return oldUserRe;
	}

	@Override
	@Transactional
	public int deleteUserReBy1(UserReDto deleteUserRe) {
		return this.userDao.deleteUserReBy1(deleteUserRe, new String[] {});
	}

	@Override
	@Transactional
	public int deleteUserReByIds(UserReDto deleteUserRe) {
		return this.userDao.deleteUserReByIds(deleteUserRe);
	}

	@Override
	@Transactional
	public int setUserReBy1(UserReDto setUserRe) {
		return this.userDao.updateUserReBy1(setUserRe, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	public int setUserReBy2(UserReDto setUserRe) {
		return this.userDao.updateUserReBy2(setUserRe);
	}

	@Override
	public Integer readUserReByCodeNqIdForInteger(UserReDto readUserRe) {
		return this.userDao.selectUserReByCodeNqIdForInteger(readUserRe);
	}

	@Override
	public Integer readUserReBy2ForInteger(UserReDto readUserRe) {
		return this.userDao.selectUserReBy2ForObject(Integer.class, readUserRe, null);
	}

	@Override
	public List<Integer> readListUserReBy1(UserReDto readUserRe) {
		return this.userDao.selectUserReBy1ForObjectList(Integer.class, readUserRe, null,
				new String[] {});
	}

	@Override
	public List<Integer> readListUserReBy2(UserReDto readUserRe) {
		return this.userDao.selectUserReBy2ForObjectList(Integer.class, readUserRe, null);
	}

	@Override
	public UserReDto getUserReBy1(UserReDto getUserRe) {
		return this.userDao.selectUserReBy1ForMappedObject(UserReDto.class, getUserRe, null, "id");
	}

	@Override
	public UserReDto getUserReById(UserReDto getUserRe) {
		return this.userDao.selectUserReBy1ForMappedObject(UserReDto.class, getUserRe, null, "id");
	}

	@Override
	public List<UserReDto> findUserReBy1(UserReDto findUserRe) {
		return this.userDao.selectUserReBy1ForMappedObjectList(UserReDto.class, findUserRe,
				new String[] {}, new String[] {});
	}

	@Override
	public List<UserReDto> findUserReBy2(UserReDto findUserRe) {
		return this.userDao.selectUserReBy2ForMappedObjectList(UserReDto.class, findUserRe);
	}

	@Override
	public PaginationDto<UserReDto> paginationUserReBy1ForUserReList(UserReDto paginationUserRe) {
		return this.userDao.paginationUserReBy1ForMappedObjectList(UserReDto.class,
				paginationUserRe);
	}

	@Override
	public PaginationDto<Map<String, Object>> paginationUserReBy1ForMapList(UserReDto paginationUserRe) {
		return this.userDao.paginationUserReBy1ForMapList(paginationUserRe);
	}
}